package com.service.admin.member.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.service.admin.member.controller.rep.MemberPgeRep;
import com.service.admin.member.controller.rep.StoreCountPageRep;
import com.service.admin.member.controller.req.StoreCountPageReq;
import com.service.admin.member.dto.MemberStoreChange;
import com.service.admin.member.service.MemberService;
import com.service.admin.support.MemberStoreLockUtils;
import com.service.core.rest.response.CommonPageRep;
import com.service.dao.enums.CoinsEnum;
import com.service.dao.enums.CommonStatusEnums;
import com.service.dao.enums.MemberJAType;
import com.service.dao.mapper.*;
import com.service.dao.model.*;
import com.service.admin.member.service.MemberStoreService;
import com.service.utility.modelmapper.ModelMapperUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;


/**
 * <dl>
 * <dt>back-end</dt>
 * <dd>Description:</dd>
 * <dd>Copyright: Copyright (C) 2015</dd>
 * <dd>Company: </dd>
 * <dd>CreateDate: 2019年09月24日</dd>
 * </dl>
 *
 * @author
 */
@Slf4j
@Service
@Transactional(readOnly = true, rollbackFor = Exception.class)
public class MemberStoreServiceImpl extends ServiceImpl<MemberStoreMapper, MemberStore> implements MemberStoreService {
    @Autowired
    private MemberStoreLockUtils storeLockUtils;
    @Autowired
    private MemberMapper memberMapper;
    @Autowired
    private JournalAccountMapper journalAccountMapper;
    @Autowired
    private OrderProductHrComboMapper orderProductHrComboMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public MemberStore getMemberStore(Integer memberId, String coinsName) {
        MemberStore store = getOne(new QueryWrapper<MemberStore>().lambda()
                .eq(MemberStore::getMemberId, memberId)
                .eq(MemberStore::getCoinsName, coinsName));
        if (ObjectUtils.isEmpty(store)) {
            CoinsEnum coinsEnum = CoinsEnum.valueOf(coinsName);
            store = new MemberStore();
            store.setMemberId(memberId);
            store.setCoinsId(coinsEnum.getCode());
            store.setCoinsName(coinsEnum.getName());
            store.setNum(BigDecimal.ZERO);
            store.setFrostNum(BigDecimal.ZERO);
            store.setCreateTime(new Date());
            save(store);
        }
        return store;
    }

    @Override
    @Transactional
    public Integer changeMemberStore(MemberStoreChange storeChange) {
        MemberStore memberStore = getMemberStore(storeChange.getMemberId(), storeChange.getCoinsName());
        return changeMemberStore(memberStore, storeChange);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void payByMemberStore(Integer memberId, String coinsName, MemberJAType payType, BigDecimal payMoney, Integer orderId) {
        MemberStoreChange storeChange = MemberStoreChange.builder()
                .memberId(memberId)
                .changeNum(payMoney)
                .coinsName(coinsName)
                .orderId(orderId)
                .jaType(payType)
                .remark(payType.getMsg())
                .build();
        this.changeMemberStore(storeChange);
    }

    @Override
    public CommonPageRep<StoreCountPageRep> pageMemberCount(StoreCountPageReq req) {
        Page<Member> page = PageHelper.startPage(req.getPageNo(), req.getPageSize());
        memberMapper.selectByAccount(req.getMemberAccount(), req.getMemberStatus().getCode());
        Date currentDate = new Date();
        String pattern = "yyyy-MM-dd";
        String currentDateStr = DateFormatUtils.format(currentDate, pattern);
        List<StoreCountPageRep> resultList = page.getResult().stream()
                .map(x -> ModelMapperUtil.getStrictModelMapper().map(x, StoreCountPageRep.class)).collect(Collectors.toList());
        resultList.parallelStream().forEach(item -> {
            //设置流通账户余额 开始
            List<MemberStore> memberStores = baseMapper.selectByMemberId(item.getId(), CommonStatusEnums.ACTIVE.getCode());
            memberStores.stream().forEach(memberStore -> {
                if (memberStore.getCoinsId() == CoinsEnum.FIL.getCode()) {
                    item.setCurrencyFIL(memberStore.getNum());
                } else if (memberStore.getCoinsId() == CoinsEnum.BTC.getCode()) {
                    item.setCurrencyBTC(memberStore.getNum());
                } else if (memberStore.getCoinsId() == CoinsEnum.USDT.getCode()) {
                    item.setCurrencyUSDT(memberStore.getNum());
                }
            });
            //设置流通账户余额 结束
            //统计
            item.setTodayRechargeUSDT(journalAccountMapper.getSomedayTotalStatementByCoins(item.getId(), CoinsEnum.USDT.getName(), MemberJAType.getRechargeType(), currentDateStr));
            item.setTotalRechargeUSDT(journalAccountMapper.getSomedayTotalStatementByCoins(item.getId(), CoinsEnum.USDT.getName(), MemberJAType.getRechargeType(), null));
            item.setTodayWithdrawUSDT(journalAccountMapper.getSomedayTotalStatementByCoins(item.getId(), CoinsEnum.USDT.getName(), MemberJAType.getWithdrawType(), currentDateStr));
            item.setTotalWithdrawUSDT(journalAccountMapper.getSomedayTotalStatementByCoins(item.getId(), CoinsEnum.USDT.getName(), MemberJAType.getWithdrawType(), null));
            item.setTodayWithdrawFIL(journalAccountMapper.getSomedayTotalStatementByCoins(item.getId(), CoinsEnum.FIL.getName(), MemberJAType.getWithdrawType(), currentDateStr));
            item.setTotalWithdrawFIL(journalAccountMapper.getSomedayTotalStatementByCoins(item.getId(), CoinsEnum.FIL.getName(), MemberJAType.getWithdrawType(), null));
            item.setTodayReleaseFIL(journalAccountMapper.getSomedayTotalStatementByCoins(item.getId(), CoinsEnum.FIL.getName(), MemberJAType.getReleaseType(), currentDateStr));
            item.setTotalReleaseFIL(journalAccountMapper.getSomedayTotalStatementByCoins(item.getId(), CoinsEnum.FIL.getName(), MemberJAType.getReleaseType(), null));
            item.setTodayReleaseBTC(journalAccountMapper.getSomedayTotalStatementByCoins(item.getId(), CoinsEnum.BTC.getName(), MemberJAType.getReleaseType(), currentDateStr));
            item.setTotalReleaseBTC(journalAccountMapper.getSomedayTotalStatementByCoins(item.getId(), CoinsEnum.BTC.getName(), MemberJAType.getReleaseType(), null));
            item.setTodayBuyFIL(orderProductHrComboMapper.totalTodayBuyByMemberIdAndCoinsIdAndSomeDay(item.getId(), CoinsEnum.FIL.getName(), currentDateStr));
            item.setTotalBuyFIL(orderProductHrComboMapper.totalTodayBuyByMemberIdAndCoinsIdAndSomeDay(item.getId(), CoinsEnum.FIL.getName(), null));
            item.setTodayBuyBTC(orderProductHrComboMapper.totalTodayBuyByMemberIdAndCoinsIdAndSomeDay(item.getId(), CoinsEnum.BTC.getName(), currentDateStr));
            item.setTotalBuyBTC(orderProductHrComboMapper.totalTodayBuyByMemberIdAndCoinsIdAndSomeDay(item.getId(), CoinsEnum.BTC.getName(), null));
        });
        return CommonPageRep.buildResultRep(page, resultList);
    }

    @Override
    public List<MemberStore> selectByMemberId(Integer memberId, Integer coinStatus) {
        return baseMapper.selectByMemberId(memberId, coinStatus);
    }

    @Override
    public BigDecimal totalStatementByParam(String coinsName) {
        return baseMapper.totalStatementByParam(coinsName);
    }

    @Transactional
    public Integer changeMemberStore(MemberStore memberStore, MemberStoreChange storeChange) {
        Integer storeId = memberStore.getId();
        storeChange.getJaType().doOptStore(memberStore, storeChange.getChangeNum());
        BigDecimal storeNumNow = memberStore.getNum();
        BigDecimal frostNum = memberStore.getFrostNum();
        JournalAccount journalAccount = JournalAccount.builder()
                .storeId(memberStore.getId())
                .storeNum(memberStore.getNum())
                .coinsId(memberStore.getCoinsId())
                .coinsName(memberStore.getCoinsName())
                .storeFrostNum(memberStore.getFrostNum())
                .memberId(storeChange.getMemberId())
                .jaNum(storeChange.getChangeNum())
                .jaType(storeChange.getJaType().getCode())
                .jaRemark(storeChange.getRemark())
                .orderId(storeChange.getOrderId())
                .orderDetailId(storeChange.getOrderDetailId())
                .jaId(storeChange.getJaId())
                .createTime(new Date())
                .build();

        memberStore = new MemberStore();
        memberStore.setId(storeId);
        memberStore.setNum(storeNumNow);
        memberStore.setFrostNum(frostNum);
        updateById(memberStore);

        journalAccountMapper.insert(journalAccount);

        return journalAccount.getId();
    }

}
